/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.mach.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import io.jsonwebtoken.lang.Collections;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;

import javax.sql.rowset.serial.SerialException;
import javax.validation.Valid;

import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springblade.common.cache.DictCache;
import org.springblade.common.cache.UserCache;
import org.springblade.common.constant.ResultConstant;
import org.springblade.common.enums.DictEnum;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.*;
import org.springblade.flow.business.service.FlowBusinessService;
import org.springblade.mach.entity.*;
import org.springblade.mach.service.*;
import org.springblade.mach.utils.ExcelUtils;
import org.springblade.mach.utils.MachUtils;
import org.springblade.mach.vo.SignDrawingUploadVO;
import org.springblade.modules.resource.builder.oss.OssBuilder;
import org.springblade.modules.resource.builder.oss.UploadFileBuilder;
import org.springblade.modules.resource.entity.Attach;
import org.springblade.modules.resource.service.IAttachService;
import org.springblade.modules.resource.vo.AttachVO;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.mach.vo.DrawingUploadVO;
import org.springblade.mach.wrapper.DrawingUploadWrapper;
import org.springblade.core.boot.ctrl.BladeController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 控制器
 *
 * @author LY
 * @since 2021-03-09
 */
@RestController
@AllArgsConstructor
@RequestMapping("data-drawing-attach/drawingupload")
@Api(value = "", tags = "接口")
public class DrawingUploadController extends BladeController {

	private final IDrawingUploadService drawingUploadService;

	// 图库信息
	private IDrawingInfoService drawingInfoService;

	// 附件表服务
	private final IAttachService attachService;
	private final FlowBusinessService flowBusinessService;
	private MachUtils machUtils;


	/**
	 * @param ids
	 * @return org.springblade.core.tool.api.R
	 * 提交审批
	 * @Author zhp
	 * @Description //TODO
	 * @Date 11:25 2021/12/15
	 */
	@PostMapping("/changeUploadStatus")
	@Transactional(rollbackFor = Exception.class)
	public R changeUploadStatus(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		// step1:修改记录的列表id
		List<Long> idList = Func.toLongList(ids);
		if (!Collections.isEmpty(idList)) {
			DrawingUpload drawingUpload = new DrawingUpload();
			drawingUpload.setStatus(DrawingUpload.STATUS_APPROVAL);
			boolean update = drawingUploadService.update(drawingUpload,
				new QueryWrapper<DrawingUpload>().lambda().in(DrawingUpload::getId, idList));
			return R.status(update);
		} else {
			return R.status(false);
		}
	}


	/**
	 * @param
	 * @return 检查前端页面传入得excel信息是否正确
	 */
	/*@PostMapping("/excel")
	@Transactional(rollbackFor = Exception.class)
	public R<Map<String, Object>> getExcel(MultipartFile[] file,
										   MultipartFile[] threeFile,
										   MultipartFile[] imgFile,
										   DrawingUpload drawingUpload) throws IOException, SerialException {

		List<String> codeErrorList = new ArrayList<>();
		Map<String, Object> pageMap = new HashMap<>();
//		// #正式环境中
//		if (file.length>0) {
//			// step1:检验excel中代号是否申请过
//			for (int i = 0; i < file.length ; i++) {
//				if (!file[i].isEmpty()) {
//					MultipartFile indexFile = file[i];
//					String fileExtension = FileUtil.getFileExtension(indexFile.getOriginalFilename());
//					if (fileExtension.equals("xls") || fileExtension.equals("xlsx")) {
//						List<String> checkResult = checkExcel(indexFile);
//						if (checkResult.size()>0) {
//							codeErrorList.addAll(checkResult);
//						}
//					}
//				}else {
//					throw new SerialException("文件不可为空文件");
//				}
//			}
//			// step2:校验两件以上的01+的设备是否上传了对应的bom信息
//			List<String> checkBomResult = checkBom(file);
//			if (checkBomResult.size()>0) {
//				codeErrorList.addAll(checkBomResult);
//			}
//		}
//		// 前端页面错误信息展示
//		if (codeErrorList.size()>0) {
//			pageMap.put("error",codeErrorList);
//		}else{
//			// step3:信息无误，则存入Minio服务器中,前端展示的状态为 未审核状态
//			List<Attach> attachList = new ArrayList<>();   //附件列表信息
//			List<DrawingUploadDetail> detailList = new ArrayList<>();   // 设备以及图纸的对应信息
//			if (file.length>0) {
//		        drawingUpload.setStatus(1);
//				boolean saveDrawingUpload = drawingUploadService.save(drawingUpload);
//				for (int i = 0; i <file.length ; i++) {
//					MultipartFile indexFile = file[i];
//					if (!indexFile.isEmpty()) {
//						String fileName = indexFile.getOriginalFilename();
////		                bladeFile = ossBuilder.template().putFile(fileName,indexFile.getInputStream());
//		                bladeFile = UploadFileBuilder.handlePutFile(fileName,indexFile,indexFile.getInputStream());
//						Attach attach =  buildAttach(fileName, indexFile.getSize(), bladeFile);
//						attach.setType("平面");
//						attachList.add(attach);
//						// 详情表
//						DrawingUploadDetail detail =  new DrawingUploadDetail();
//						detail.setAttachId(attach.getId());
//						detail.setUploadId(drawingUpload.getId());
//						detailList.add(detail);
//					}
//
//				}
//				// 三维图纸上传
//				for (int i = 0; i < threeFile.length; i++) {
//					MultipartFile indexFile = threeFile[i];
//					if (!indexFile.isEmpty()) {
//						String fileName = indexFile.getOriginalFilename();
//						BladeFile bladeFile = ossBuilder.template().putFile(fileName,indexFile.getInputStream());
//						Attach attach =  buildAttach(fileName, indexFile.getSize(), bladeFile);
//						attach.setType("三维");
//						attachList.add(attach);
//						// 详情表
//						DrawingUploadDetail detail =  new DrawingUploadDetail();
//						detail.setAttachId(attach.getId());
//						detail.setUploadId(drawingUpload.getId());
//						detailList.add(detail);
//					}
//				}
//				// 图片上传
//				for (int i = 0; i <imgFile.length ; i++) {
//					MultipartFile indexFile = imgFile[i];
//					if (!indexFile.isEmpty()) {
//						String fileName = indexFile.getOriginalFilename();
//						BladeFile bladeFile = UploadFileBuilder.handlePutFile(fileName, indexFile, ossBuilder);
//						Attach attach =  buildAttach(fileName, indexFile.getSize(), bladeFile);
//						attach.setType("图片");
//						attachList.add(attach);
//		                saveAttach = attachService.save(attach);
//						// 附件详情表
//						DrawingUploadDetail detail =  new DrawingUploadDetail();
//						detail.setAttachId(attach.getId());
//						detail.setUploadId(drawingUpload.getId());
//						detailList.add(detail);
//					}
//
//				}
//
//				boolean saveAttach = attachService.saveBatch(attachList);
//				boolean saveDetail = drawingUploadDetailService.saveBatch(detailList);
//				if (saveDrawingUpload && saveAttach && saveDetail) {
//					pageMap.put("right","上传成功");
//				}
//
//			}
//		}

		// #测试环境中
		List<Attach> attachList = new ArrayList<>();   //附件列表信息
		List<DrawingUploadDetail> detailList = new ArrayList<>();   // 设备以及图纸的对应信息
		Boolean saveAttach = false;
		if (file.length > 0) {
			drawingUpload.setStatus(1);
			boolean saveDrawingUpload = drawingUploadService.save(drawingUpload);
			// excel文件
			SaveAttached(file, *//*attachList,*//* detailList, drawingUpload, "平面", saveAttach);
			// 三维图纸上传
			SaveAttached(threeFile, *//*attachList,*//* detailList, drawingUpload, "三维", saveAttach);
			// 图片上传
			SaveAttached(imgFile, *//*attachList,*//* detailList, drawingUpload, "图片", saveAttach);
			boolean saveDetail = drawingUploadDetailService.saveBatch(detailList);
			if (saveDrawingUpload && saveAttach && saveDetail) {
				pageMap.put("right", "上传成功");
			}
		}
		return R.data(pageMap);
	}
*/


	/**
	 * 校验01+以上的设备，是否有对应的bom信息
	 */



	/**
	 * 查找图纸信息excel、pdf、dwg
	 */
	@GetMapping("/getPdfByUploadId")
	public R<List<AttachVO>> getPdfByUploadId(@RequestParam("id") Long id) {
		return R.data(attachService.getDrawingByUploadId(id));
	}

	/**
	 * 根据upload找到 相应的三维图纸
	 */
	@GetMapping("/getThreeByUploadId")
	public R<List<AttachVO>> getAttachByUploadId(@RequestParam("id") Long id) {
		return R.data(attachService.getThreeDrawingByUploadId(id));
	}

	/**
	 * 根据upload找到 找到相应的图片信息
	 */
	@GetMapping("/getImgListByUploadId")
	public R<List<AttachVO>> getImgListByUploadId(@RequestParam("id") Long id) {
		return R.data(attachService.getImgListByUploadId(id));
	}


	/**
	 * 修改excel附件中的内容
	 * 附件上传 上传附件提交
	 */
	@PostMapping("/updateExcel")
	@Transactional(rollbackFor = Exception.class)
	public R<Map<String, Object>> editExcelFun(MultipartFile[] file,
											   MultipartFile[] threeFile,
											   MultipartFile[] imgFile,
											   @ModelAttribute("drawingUpload") DrawingUpload drawingUpload,
											   @ModelAttribute("fileTyeList") FileTyeList fileTyeList,
											   @ModelAttribute("fileThreeTypeList") FileThreeTypeList fileThreeTypeList,
											   @ModelAttribute("fileImgTypeList") FileImgTypeList fileImgTypeList) throws IOException {

		Map<String, Object> pageMap = new HashMap<>();
		List<String> codeErrorList = new ArrayList<>();
		//List<DrawingUploadDetail> detailList = new ArrayList<>();   // 设备以及图纸的对应信息
		if (null == file) {
			pageMap.put("error", "参数为空");
			return R.data(pageMap);
		}
		/*  业务流程：
			1.先判断上传的bom表里的图号是否申请过
			2.然后拆分bom表里的整套图纸，判断数据库中是否存在该图纸，如是->可以不上传，如否->检验上传的附件中是否存在该图纸
			3.如果前面的验证若存在问题则返回前端错误信息，让用户修正
			4.如所有验证无误则上传附件
		 */
		drawingUploadService.applyNumberCheck(file, codeErrorList);
		// 正式环境中使用如下代码
		if (CollectionUtils.isNotEmpty(codeErrorList)) {
			pageMap.put("error", codeErrorList);
			return R.data(pageMap);
		} else {
			return drawingUploadService.saveUploadAttach(file, threeFile, imgFile, drawingUpload, fileTyeList,
				fileThreeTypeList, fileImgTypeList);
		}
	}

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入drawingAttach")
	public R<DrawingUploadVO> detail(DrawingUpload drawingAttach) {
		DrawingUpload detail = drawingUploadService.getOne(Condition.getQueryWrapper(drawingAttach));
		DrawingUploadVO drawingUploadVO = DrawingUploadWrapper.build().entityVO(detail);
		return R.data(drawingUploadVO);
	}

	/**
	 * 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入drawingAttach")
	public R<IPage<DrawingUploadVO>> list(@RequestParam Map<String, Object> drawingUpload, Query query) {
		final BladeUser user = AuthUtil.getUser();
		IPage<DrawingUpload> pages = drawingUploadService.page(
			Condition.getPage(query), Condition.getQueryWrapper(drawingUpload, DrawingUpload.class)
				.eq("status", DrawingUpload.STATUS_PENDING)
				.eq("create_user", user.getUserId())
				.lambda().orderByDesc(DrawingUpload::getCreateTime));
		IPage<DrawingUploadVO> drawingUploadVOIPage = DrawingUploadWrapper.build().pageVO(pages);
		drawingUploadVOIPage.getRecords().stream().forEach(drawingUploadVO -> {
			drawingUploadVO.setUserAccount(UserCache.getUser(drawingUploadVO.getCreateUser()).getAccount());
			drawingUploadVO.setStatusName(DictCache.getValue(DictEnum.PROCESS_STATUS, drawingUploadVO.getStatus()));

		});
		return R.data(drawingUploadVOIPage);
	}


	/**
	 * 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入drawingAttach")
	public R<IPage<DrawingUploadVO>> page(DrawingUploadVO drawingAttach, Query query) {
		IPage<DrawingUploadVO> pages = drawingUploadService.selectDrawingAttachPage(Condition.getPage(query), drawingAttach);
		return R.data(pages);
	}

	/**
	 * 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入drawingAttach")
	public R save(@Valid @RequestBody DrawingUpload drawingAttach) {
		return R.status(drawingUploadService.save(drawingAttach));
	}

	/**
	 * 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入drawingAttach")
	public R update(@Valid @RequestBody DrawingUpload drawingAttach) {
		return R.status(drawingUploadService.updateById(drawingAttach));
	}

	/**
	 * 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入drawingAttach")
	public R submit(@Valid @RequestBody DrawingUpload drawingAttach) {
		return R.status(drawingUploadService.saveOrUpdate(drawingAttach));
	}


	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	@Transactional(rollbackFor = Exception.class)
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return drawingUploadService.removeAttach(ids);
	}

	/**
	 * 发起事务->撤回
	 * 图纸审批状态更新，归档接口
	 * @param drawingUpload
	 * @return
	 */
	@SneakyThrows
	@RequestMapping("/updateDrawingStatus")
	@Transactional(rollbackFor = Exception.class)
	public R updateDrawingStatus(@RequestBody DrawingUpload drawingUpload) {
		// 图纸更新审批状态
		Boolean result;
		//标准化审核同意后拆分BOM
		if (drawingUpload != null && drawingUpload.getFlow() != null && StringUtil.isNotBlank(drawingUpload.getFlow().getTaskDefinitionKey())) {
			if ("normalizing".equals(drawingUpload.getFlow().getTaskDefinitionKey()) && drawingUpload.getFlow().isPass()) {
				drawingUploadService.getDrawingBom(drawingUpload.getId());
				//修改图纸上传状态为已归档
				result = drawingUploadService.updateDrawingUploadStatus(drawingUpload.getId(), DrawingUpload.STATUS_ARCHIVE);
				// 拆分bom
			}else {
				//修改图纸上传状态为审批中
				result = drawingUploadService.updateDrawingStatus(drawingUpload.getId(), DrawingUpload.STATUS_APPROVAL);
			}
			//提交流程
			flowBusinessService.completeTask(drawingUpload.getFlow());
		//撤回操作
		}else {
			//修改图纸上传状态为待审批
			result = drawingUploadService.updateDrawingStatus(drawingUpload.getId(), DrawingUpload.STATUS_PENDING);
		}

		/*if (Attach.ATTACH_STATUS_FILED.equals(statusCode)) {
			// 附件归档
			// 获取附件id列表
			List<Long> attachIdList = drawingUploadDetailService.findAttachIdList(drawingUpload.getId());
			// 批量修改附件归档状态
			attachService.uploadAttachStatus(attachIdList, statusCode);
		}*/
		return R.data(result);
	}


	/**
	 * 上传替换签名后的图纸信息
	 *
	 * @return
	 */
	@PostMapping("/submitSignAttach")
	@Transactional(rollbackFor = Exception.class)
	public  R<Map<String, Object>> submitSignAttach(SignDrawingUploadVO signDrawingUploadVO) throws IOException {
		Map<String, Object> pageMap = new HashMap<>();
		List<String> codeErrorList = new ArrayList<>();
		if (null == signDrawingUploadVO) {
			pageMap.put("error", "参数为空");
			return R.data(pageMap);
		}
		//参数校验
		MultipartFile[] planeFile = signDrawingUploadVO.getPlaneFile();
		drawingUploadService.applyNumberCheck(planeFile, codeErrorList);
		if (CollectionUtils.isNotEmpty(codeErrorList)) {
			pageMap.put("error", codeErrorList);
			return R.data(pageMap);
		} else {
			return drawingUploadService.saveSignAttach(signDrawingUploadVO);
		}
	}


	/**
	 * 图纸的全部bom附件
	 *
	 * @param uploadId
	 * @return
	 */
	@GetMapping("/findDrawingListByUploadId")
	public R findDrawingListByUploadId(@RequestParam(value = "uploadId") Long uploadId,
									   @RequestParam(value = "taskDefinitionKey") String taskDefinitionKey) {
		return R.data(attachService.findDrawingListByUploadId(uploadId, taskDefinitionKey));
	}

	/**
	 * 驳回删除所有的附件
	 *
	 * @param uploadId
	 * @param taskDefinitionKey
	 * @return
	 */
	@GetMapping("/deleteDrawingAttach")
	@Transactional(rollbackFor = Exception.class)
	public R deleteDrawingAttach(@RequestParam(value = "uploadId") Long uploadId,
								 @RequestParam(value = "taskDefinitionKey") String taskDefinitionKey) {
		R<Object> r = new R<>();
		if (null == uploadId && StringUtil.isEmpty(taskDefinitionKey)) {
			r = R.fail(ResultConstant.PARAM_EMTPY_ERROR);
		} else {
			// 删除附件及关联数据信息
			r = drawingUploadService.handleDrawingAttach(uploadId, taskDefinitionKey);
		}

		return r;
	}

}
